package com.fjwt.gz.service.activity.coupon.notify;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fjwt.gz.core.constants.ApiCodeEnum;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.core.utils.SpringBeansUtil;
import com.fjwt.gz.coupon.yspay.YspayCouponWriteNotifyService;
import com.fjwt.gz.coupon.yspay.YspayIsvParams;
import com.fjwt.gz.coupon.yspay.yspayutil.RSA256Util;
import com.fjwt.gz.coupon.yspay.yspayutil.SignUtil;
import com.fjwt.gz.db.entity.AwardCouponNotifyEntity;
import com.fjwt.gz.db.entity.FansAwardEntity;
import com.fjwt.gz.db.entity.PayOrderEntity;
import com.fjwt.gz.interfaces.ChannelCouponWriteService;
import com.fjwt.gz.service.impl.*;
import com.fjwt.gz.service.activity.BaseActivityService;
import com.fjwt.gz.util.ChannelCertConfigKitBean;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class YspayCouponWriteService implements ChannelCouponWriteService {

    private static final Logger ysPayLogger = LoggerFactory.getLogger("ysPay");

    @Autowired
    private AwardCouponNotifyService couponNotifyService;
    @Autowired
    private FansAwardService fansAwardService;
    @Autowired
    private PayOrderService payOrderService;
    @Autowired
    private ScoreRecordTotalService scoreRecordService;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private YspayCouponWriteNotifyService yspayCouponWriteNotifyService;

    private static String logPrefix = "银盛卡券核销回调:";

    @Override
    public String addNotifyRecord(Map<String, Object> requestMap) {
        JSONObject respJson = new JSONObject();
        ysPayLogger.info(logPrefix + "添加回调信息记录进来的参数是：{}", JSONUtil.toJsonStr(requestMap));
        String sysConfig = sysConfigService.getIfCode("yspay");
        ysPayLogger.info("{},支付通道配置信息：{}", logPrefix, JSONUtil.toJsonStr(sysConfig));
        YspayIsvParams yspayIsvParams = JSONObject.parseObject(sysConfig, YspayIsvParams.class);
        ysPayLogger.info("{},支付参数：{}", logPrefix, JSONUtil.toJsonStr(yspayIsvParams));
        Map<String, String> map = new HashMap<>();

        for (String key : requestMap.keySet()) {
            map.put(key, requestMap.get(key).toString());
        }

        ysPayLogger.info("{},map复制后的信息：{}", logPrefix, JSONUtil.toJsonStr(map));
        boolean verifyResult = false;
        try {

            //验签
            /*3、调用异步通知验签方法*/
            byte[] srcData = SignUtil.getSignDataStr1(map).getBytes("UTF-8");
            ChannelCertConfigKitBean channelCertConfigKitBean = SpringBeansUtil.getBean(ChannelCertConfigKitBean.class);
            //银盛端的公钥证书
            boolean validateSignResult = RSA256Util.validateSign(channelCertConfigKitBean.getCertFilePath(yspayIsvParams.getYsPublicCer()), cn.hutool.core.codec.Base64.decode(map.get("sign")), srcData);
            ysPayLogger.info("验签结果：{}", validateSignResult);
            if (!validateSignResult) {
                ysPayLogger.info("{}:y验签失败:{}", logPrefix, validateSignResult);
                return JSONUtil.toJsonStr(ApiRes.fail(ApiCodeEnum.CUSTOM_FAIL, "卡券核销失败"));
            }

        } catch (Exception e) {
            ysPayLogger.info("{},验签异常", logPrefix);
            e.printStackTrace();
        }

        JSONObject json = JSONObject.parseObject(MapUtil.getStr(requestMap, "bizContent"));
        ysPayLogger.info(logPrefix + "bizContent:{}", JSONUtil.toJsonStr(json));
        String couponThirdId = json.getString("couponId");
        ysPayLogger.info(logPrefix + "三方卡券ID:{}", couponThirdId);
        Date date = new Date();
        AwardCouponNotifyEntity couponNotifyEntity = new AwardCouponNotifyEntity();
        LambdaQueryWrapper<FansAwardEntity> fansAwardGw = FansAwardEntity.gw();
        fansAwardGw.eq(FansAwardEntity::getCouponThirdId, couponThirdId);
        FansAwardEntity fansAwardEntity = fansAwardService.getBaseMapper().selectOne(fansAwardGw);
        if (ObjectUtil.isEmpty(fansAwardEntity)) {
            ysPayLogger.info("卡券ID：{}，此卡券不是营销平台创建，直接返回，不记录数据库", couponThirdId);
            respJson.put("code", 10000);
            return JSONUtil.toJsonStr(ApiRes.fail(ApiCodeEnum.SYS_TLPAY_SUCCESS_COUPON_NOTIFY));
        }
        String noticeMessageStr = json.getString("noticeMessage");
        JSONObject noticeMessageJson = JSONObject.parseObject(noticeMessageStr);
        if ("USED".equals(noticeMessageJson.getString("status"))) {
            couponNotifyEntity.setNotifyState(0);//已核销
        } else if ("SENDED".equals(noticeMessageJson.getString("status"))) {
            couponNotifyEntity.setNotifyState(1);//未核销
        } else if ("EXPIRED".equals(noticeMessageJson.getString("status"))) {
            couponNotifyEntity.setNotifyState(2);//已过期
        }
        couponNotifyEntity.setCouponThirdId(couponThirdId);
        couponNotifyEntity.setIfcode("yspay");
        couponNotifyEntity.setState(1);//回调进来的都是状态1未同步
        couponNotifyEntity.setNotifyJson(JSONUtil.toJsonStr(requestMap));
        couponNotifyEntity.setCreatedAt(date);
        couponNotifyEntity.setUpdatedAt(date);
        couponNotifyEntity.setSourceType(1);
        ysPayLogger.info(logPrefix + "添加回调信息记录:{}", JSONUtil.toJsonStr(couponNotifyEntity));
        boolean save = couponNotifyService.save(couponNotifyEntity);
        if (save == true) {
            ysPayLogger.info("银盛回调成功返回：{}", "success");
            return "success";
        } else {
            return JSONUtil.toJsonStr(ApiRes.fail(ApiCodeEnum.CUSTOM_FAIL, "卡券异步回调通知处理失败！"));
        }
    }

    @Override
    public Map<String, Object> paraseParamters(HttpServletRequest request) throws IOException {
        return yspayCouponWriteNotifyService.paraseParamters(request, null);
    }

    @Override
    public void couponDoNotice(AwardCouponNotifyEntity couponNotifyEntity) throws Exception {
        ysPayLogger.info(logPrefix + "处理逻辑进来的参数是：{}", JSONUtil.toJsonStr(couponNotifyEntity));
        //通过卡券三方id是否存在，如不存在，更新回调记录表，添加备注
        LambdaQueryWrapper<FansAwardEntity> fansAwardGw = FansAwardEntity.gw();
        fansAwardGw.eq(FansAwardEntity::getCouponThirdId, couponNotifyEntity.getCouponThirdId());
        FansAwardEntity fansAwardEntity = fansAwardService.getBaseMapper().selectOne(fansAwardGw);

        if (ObjectUtil.isNotEmpty(fansAwardEntity)) {
            if (fansAwardEntity.getState() == 1) {
                //卡券不是英雄啊平台创建
                AwardCouponNotifyEntity couponNotifyUpdate = new AwardCouponNotifyEntity();
                couponNotifyUpdate.setCouponNotifyId(couponNotifyEntity.getCouponNotifyId());
                couponNotifyUpdate.setState(2);
                couponNotifyUpdate.setRemark("此订单已经推送过");
                ysPayLogger.info(logPrefix + "处理逻辑,此卡券此订单已经推送过,更新的数据是：{}", JSONUtil.toJsonStr(couponNotifyUpdate));
                couponNotifyService.updateById(couponNotifyUpdate);
            } else {
                // 处理卡券核销是否进行奖励积分
                scoreRecordService.couponWriteSendScore(fansAwardEntity);
                //是卡券营销平台创建,卡券核销后的处理
                ysPayLogger.info(logPrefix + "extraJson:{}", fansAwardEntity.getExtraJson());
                JSONObject extraJson = JSONObject.parseObject(fansAwardEntity.getExtraJson());
                if (ObjectUtil.isNotEmpty(extraJson)) {
                    String templateNo = extraJson.getString("templateNo");
                    BaseActivityService activityService = SpringBeansUtil.getBean(templateNo + "Service", BaseActivityService.class);
                    // 支付通道接口实现不存在
                    if (activityService == null) {
                        ysPayLogger.info(templateNo + "Service,接口不存在");
                        throw new BizException(templateNo + "Service,接口不存在");
                    }
                    JSONObject json = JSONObject.parseObject(JSONUtil.toJsonStr(fansAwardEntity));
                    activityService.run(json);
                }
                FansAwardEntity fansAwardEntityUpdate = new FansAwardEntity();
                fansAwardEntityUpdate.setFansAwardId(fansAwardEntity.getFansAwardId());
                fansAwardEntityUpdate.setState(1);
                //使用三方的核销时间
                if (StringUtils.isNotEmpty(couponNotifyEntity.getNotifyJson())) {
                    JSONObject notifyJson = JSONObject.parseObject(couponNotifyEntity.getNotifyJson());
                    JSONObject bizContent = JSONObject.parseObject(notifyJson.getString("bizContent"));
                    JSONObject noticeMessage = JSONObject.parseObject(bizContent.getString("noticeMessage"));
                    JSONObject consumeInformation = JSONObject.parseObject(noticeMessage.getString("consumeInformation"));
                    fansAwardEntityUpdate.setWriteTime(DateUtil.parse(consumeInformation.getString("consumeTime")));
                } else {
                    fansAwardEntityUpdate.setWriteTime(new Date());
                }
                //如果能通过三方卡券id查询到订单，则添加商户号，（此订单核销属于新平台的订单，如果没有则表示是老平台的订单，就没有商户号）
                LambdaQueryWrapper<PayOrderEntity> payOrderGw = PayOrderEntity.gw();
                payOrderGw.eq(PayOrderEntity::getCouponThirdId, fansAwardEntity.getCouponThirdId());
                PayOrderEntity payOrderEntity = payOrderService.getBaseMapper().selectOne(payOrderGw);
                if (ObjectUtil.isNotEmpty(payOrderEntity)) {
                    fansAwardEntityUpdate.setMchNo(payOrderEntity.getMchNo());
                }
                ysPayLogger.info(logPrefix + "此卡券核销更新数据，更新数据的信息是：{}", JSONUtil.toJsonStr(fansAwardEntityUpdate));
                fansAwardService.updateById(fansAwardEntityUpdate);

                //更新回调数据状态
                AwardCouponNotifyEntity couponNotifyUpdate = new AwardCouponNotifyEntity();
                couponNotifyUpdate.setCouponNotifyId(couponNotifyEntity.getCouponNotifyId());
                couponNotifyUpdate.setState(2);
                couponNotifyUpdate.setRemark("核销成功");
                ysPayLogger.info(logPrefix + "核销成功,更新的数据是：{}", JSONUtil.toJsonStr(couponNotifyUpdate));
                couponNotifyService.updateById(couponNotifyUpdate);
            }
        } else {
            //卡券不是英雄啊平台创建
            AwardCouponNotifyEntity couponNotifyUpdate = new AwardCouponNotifyEntity();
            couponNotifyUpdate.setCouponThirdId(couponNotifyEntity.getCouponThirdId());
            couponNotifyUpdate.setState(2);
            couponNotifyUpdate.setRemark("此卡券不是营销平台创建");
            ysPayLogger.info(logPrefix + "处理逻辑,此卡券不是营销平台创建,更新的数据是：{}", JSONUtil.toJsonStr(couponNotifyUpdate));
            couponNotifyService.updateById(couponNotifyUpdate);
        }
    }
}
